#include "spark_llm_server.h"

#include "audio_thread.h"
#include "conf.h"
#include "utils/cJSON.h"

#include <iostream>
#include <cstring>
#include <algorithm>
#include <sstream>

std::string SparkServer::buffer = "";
bool SparkServer::is_post_done = true;

std::function<void(const std::string&)> SparkServer::user_stream_callback = nullptr;
std::function<void(const std::string&)> SparkServer::user_callback = nullptr;

namespace{
std::string parseServerJson(const std::string& response)
{
    if (response.empty()) {
        std::cerr << "[Error]: response is empty." << std::endl;
        return "";
    }

    // 使用 c_str() 将 std::string 转换为 const char*，然后传给 cJSON_Parse
    cJSON* root = cJSON_Parse(response.c_str());
    if (!root) {
        std::cerr << "[Error]: parse response failed." << std::endl;
        return "";
    }

    // 接析出错误
    cJSON* error = cJSON_GetObjectItem(root, "error");
    if (error) {
        cJSON* message = cJSON_GetObjectItem(error, "message");
        if (message) {
            std::cerr << "response wrong: " << message->valuestring << std::endl;
        }
        cJSON_Delete(root);
        return "";
    }

    // 正常解析内容
    cJSON* choices = cJSON_GetObjectItem(root, "choices");
    if (!choices) {
        std::cerr << "choices array not found." << std::endl;
        cJSON_Delete(root);
        return "";
    }

    cJSON* tmp = cJSON_GetArrayItem(choices, 0);
    if (!tmp) {
        std::cerr << "Failed to get the first item from choices." << std::endl;
        cJSON_Delete(root);
        return "";
    }

    cJSON* delta = cJSON_GetObjectItem(tmp, "delta");
    if (!delta) {
        std::cerr << "Failed to get delta from the first choice." << std::endl;
        cJSON_Delete(root);
        return "";
    }

    cJSON* content = cJSON_GetObjectItem(delta, "content");
    if (!content || content->valuestring == nullptr) {
        std::cerr << "content(cJSON*) is NULL" << std::endl;
        cJSON_Delete(root);
        return "";
    }

    // 使用 std::string 管理返回的字符串
    std::string content_out(content->valuestring);

    // 释放 cjson 申请的资源
    cJSON_Delete(root);

    return content_out;
}}


SparkServer::SparkServer() : curl(nullptr), headers(nullptr)
{
    // 初始化 curl
    // curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    init();

    buffer.clear();
    is_post_done = true;
}

SparkServer::~SparkServer() {
    if (curl != nullptr) {
        // 清理 curl
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        // curl_global_cleanup();
    }
}

bool SparkServer::init() {
    if (!curl) {
        std::cerr << "Curl initialization failed!" << std::endl;
        return false;
    }

    // 设置请求 URL
    curl_easy_setopt(curl, CURLOPT_URL, API_URL);

    // 设置请求头
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, API_AUTHOR_STR);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    return true;
}


void SparkServer::parsering_response(std::string &str)
{
    /* 通过查找[DONE]字符来判断响应是否结束 */ /* 将是否结束的标志写入 dataset */
    if (str.find("data: [DONE]") != std::string::npos) {
        // sys_log("gpt server post done.");

        is_post_done = true;
    }

    // 查找有效的 JSON 数据部分
    size_t start_pos = str.find('{');
    size_t end_pos   = str.rfind('}');

    if (start_pos != std::string::npos && end_pos != std::string::npos && 
        start_pos < end_pos) {
        str = str.substr(start_pos, end_pos - start_pos + 1);  // 提取出有效的 JSON 部分
    } else {
        str.clear();
    }

    if (!str.empty()) {
        // 从 json 中解析出真正的数据
        std::string content = parseServerJson(str);

        // 删除掉 content 中的特殊字符
        // content.erase(std::remove_if(content.begin(), content.end(), [](char c) {
        //     return c == '\n' || c == '*' || c == '.' || std::isdigit(c);
        // }), content.end());

        content.erase(std::remove_if(content.begin(), content.end(), [](char c) {
            return c == '\n' || c == '*' || c == '.';
        }), content.end());

        // sys_log("received form gpt server: %s", content.c_str());

        // 调用用户设定的流式 回调函数，每次 gpt 端返回内容的时候都会调用
        if (user_stream_callback) {
            user_stream_callback(content);
        }

        buffer += content;
    }

    // 如果响应结束的话，那么调用 callback 然后清空缓冲区
    if (is_post_done) {
        if (user_callback) {
            user_callback(buffer);
        }

        buffer.clear();
    }
}


bool SparkServer::postRequest(const std::string& question) {

    const static char *json_data = "{"
                            "\"model\": \"lite\",\"user\": \"%s\",\"messages\": [{"
                                    "\"role\": \"system\","
                                    "\"content\": \"你是一名临床经验丰富的医生。\""
                                "},{"
                                    "\"role\": \"user\", \"content\": \"%s\""
                                "}],\"stream\": true}";

    if (!curl) {
        return NULL;
    }

    std::string user_id("user");

    // 构造请求内容的 json
    int question_json_len = user_id.size() + question.size() + strlen(json_data);
    char * question_json = (char *)malloc(question_json_len * sizeof(char) + 1);
    if (question_json == NULL) {
        err_log("question json mem malloc failed.");
    }
    snprintf(question_json, question_json_len, json_data, user_id.c_str(), question.c_str());

    sys_log("post question json: %s", question_json);

    // 设置 POST 请求内容
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, question_json);

    // 设置响应的回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

    // 发送请求（阻塞进程）
    // sys_log("send question post to llm server...");
    is_post_done = false;
    CURLcode res = curl_easy_perform(curl);

    free(question_json);

    if (res != CURLE_OK) {
        std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        return false;
    }

    // 获取并打印 HTTP 状态码
    // long http_code = 0;
    // curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // std::cout << "HTTP Status Code: " << http_code << std::endl;

    return true;
}


size_t SparkServer::write_callback(void* ptr, size_t size, size_t nmemb, char* arg) {

    // std::string s((char *)ptr + 6);  // 响应的前六个字符是 "data: "
    std::string s((char *)ptr);

    // std::cout << s;

    parsering_response(s);

    // audioStrAppend(s);

    return size * nmemb;  // 需要返回正确的数据来保证持续访问
}
